#ifndef _CANARY2_NET_TCP_SERVER_H_
#define _CANARY2_NET_TCP_SERVER_H_

#include "coro_tcp.h"
#include <stop_token>
#include "../coro/task.h"
#include <netinet/in.h>
#include "sock.h"
#include "coro_tcp.h"
#include "../sys/task_manager.h"
#include <functional>
#include "listener.h"
#include "../coro/epoll_suspended_manager.h"
#include <semaphore>

namespace wilson::net
{
    class tcp_server_context
    {
    public:
        tcp_server_context(tcp_conn connection)
            : tic_conn{ ::std::move(connection) }, 
              tic_io{ tic_conn }
        {
        }

        tcp_io& get_io_ref() { return tic_io; }

    protected:
        tcp_conn    tic_conn;
        tcp_io      tic_io;
    };

    using tcp_task_callback_t = 
        ::std::function<coro::task<void>(tcp_server_context)>;

    class tcp_server
    {
    public:
        tcp_server(coro::epoll_suspend_manager& esm,
                   ipv4_address addr, in_port_t port, 
                   tcp_task_callback_t cb = nullptr);

        void set_callback(const tcp_task_callback_t& cb) { ts_callback = cb; }
        void start();
        void stop();
        void join();

    private:
        coro::task<void> listen_loop();

    private:
        ::std::binary_semaphore ts_join_sem{ 0 };
        ::std::stop_source  ts_stop_src;
        ::std::string_view  ts_name;
        socket              ts_sock;
        coro::epoll_suspend_manager& ts_suspend_mgr;
        tcp_task_callback_t ts_callback;
        listener ts_listener;
    };
}

#endif
